unit controlhelper;

{$mode objfpc}{$H+}

interface

uses
  Controls, Classes, SysUtils, StdCtrls, ExtCtrls, Spin, database, fpjson;

type

  { TParamPanels }

  TParamPanels = class
    public
      Owner: TWinControl;
      Parent: TWinControl;
      Db: TDatabase;
      ValuesAreAbsolute: Boolean;
      Panels: array [0..7] of TPanel;
      Labels: array [0..7] of TLabel;
      SpinEdits: array [0..7] of TSpinEdit;
      EditedParams: TJSONArray;

      constructor Create(AOwner, AParent: TWinControl; ADb: TDatabase);
      procedure CreatePanel(ParamId: Integer);
      procedure SetParams(Params: TJSONArray);
      procedure ParamSpinEditChange(Sender: TObject);
      destructor Destroy; override;
  end;

implementation

{ TParamPanels }

constructor TParamPanels.Create(AOwner, AParent: TWinControl; ADb: TDatabase);
begin
  Owner := AOwner;
  Parent := AParent;
  Db := ADb;
end;

procedure TParamPanels.CreatePanel(ParamId: Integer);
var
  CurrLabel: TLabel;
  Panel: TPanel;
  SpinEdit: TSpinEdit;
  ValueRange: Integer = 500;
  AbsoluteMax: Integer = 999;
begin
  if ParamId < 2 then begin
    ValueRange := 5000;
    AbsoluteMax := 9999;
  end;

  Panel := TPanel.Create(Owner);
  Panel.Parent := Parent;
  Panel.BevelInner := bvNone;
  Panel.BevelOuter := bvNone;

  CurrLabel := TLabel.Create(Owner);
  CurrLabel.Parent := Panel;
  CurrLabel.Left := Panel.Scale96ToForm(2);
  CurrLabel.Top := Panel.Scale96ToForm(2);
  CurrLabel.BorderSpacing.Space[akLeft] := Panel.Scale96ToForm(4);
  CurrLabel.BorderSpacing.Space[akTop] := Panel.Scale96ToForm(4);
  CurrLabel.BorderSpacing.Space[akRight] := Panel.Scale96ToForm(4);
  CurrLabel.Anchors := [akLeft, akTop];
  {$IF Defined(LCLGtk) or Defined(LCLGtk2) or Defined(LCLGtk2)}
  { For some reason GTK+2 version of LCL cuts a few pixels from the right
    in RTL mode, so add 2 spaces to compensate for this.

    Spaces before are used for RTL languages in the RTL mode, spaces after
    are used for LTR language in the RTL mode. }
  CurrLabel.Caption := '  ' + Db.GetParamName(ParamId) + '  ';
  {$ELSE}
  CurrLabel.Caption := Db.GetParamName(ParamId);
  {$ENDIF}
  CurrLabel.AutoSize := True;

  SpinEdit := TSpinEdit.Create(Owner);
  SpinEdit.Parent := Panel;
  if ValuesAreAbsolute then begin
    SpinEdit.MinValue := 0;
    SpinEdit.MaxValue := AbsoluteMax;
  end else begin
    SpinEdit.MinValue := -ValueRange;
    SpinEdit.MaxValue := ValueRange;
  end;
  SpinEdit.Width := Panel.Scale96ToForm(80);
  {$IF Defined(LCLGtk) or Defined(LCLGtk2) or Defined(LCLGtk2)}
  //for some reason GTK+2 version of LCL cuts a few pixels from the right
  //in RTL mode, so shift the 'left' (that is, right after mirroring) side to
  //compensate for that
  SpinEdit.BorderSpacing.Space[akLeft] := Panel.Scale96ToForm(4);
  {$ENDIF}
  SpinEdit.BorderSpacing.Space[akTop] := Panel.Scale96ToForm(2);
  SpinEdit.BorderSpacing.Space[akRight] := Panel.Scale96ToForm(4);
  SpinEdit.BorderSpacing.Space[akBottom] := Panel.Scale96ToForm(4);
  SpinEdit.AnchorSide[akLeft].Control := CurrLabel;
  SpinEdit.AnchorSide[akLeft].Side := asrLeft;
  SpinEdit.AnchorSide[akTop].Control := CurrLabel;
  SpinEdit.AnchorSide[akTop].Side := asrBottom;
  SpinEdit.Anchors := [akLeft, akTop];
  SpinEdit.AutoSize := True;
  SpinEdit.Tag := ParamId;
  SpinEdit.OnChange := @ParamSpinEditChange;

  Panel.AutoSize := True;

  SpinEdit.Show();
  CurrLabel.Show();
  Panel.Show();

  SpinEdits[ParamId] := SpinEdit;
  Labels[ParamId] := CurrLabel;
  Panels[ParamId] := Panel;
end;

procedure TParamPanels.SetParams(Params: TJSONArray);
var
  I: Integer;
begin
  EditedParams := Params;

  for I := 0 to 7 do
    if EditedParams = nil then
      SpinEdits[I].Value := 0
    else
      SpinEdits[I].Value := EditedParams.Integers[I]
end;

procedure TParamPanels.ParamSpinEditChange(Sender: TObject);
var
  SpinEdit: TSpinEdit;
begin
  SpinEdit := Sender as TSpinEdit;
  if EditedParams <> nil then
    EditedParams.Integers[SpinEdit.Tag] := SpinEdit.Value;
end;

destructor TParamPanels.Destroy;
begin

end;

end.

